<template lang="html">
  <section
    class="pull-down-container"
    @touchstart="touchstart"
    @touchmove="touchmove"
    @touchend="touchend"
    @touchcancel="touchend"
  >
    <header
      class="pull-down-header"
      :style="{'height': pullDown.height + 'px'}"
      @transitionend="transitionend"
    >
      <div class="pull-down-content">
        <i
          class="pull-down-content--icon"
          :class="iconClass"
        ></i>
        <span class="pull-down-content--label">{{label}}</span>
      </div>
    </header>
    <slot></slot>
  </section>
</template>

<script>
// import evtBus from '@/components/evtbus--index-pull_refresh'
// status of pull down
const STATUS_ERROR = -1;
const STATUS_START = 0;
const STATUS_READY = 1;
const STATUS_REFRESH = 2;
// labels of pull down
const LABELS = ['数据异常', '下拉刷新数据', '松开刷新数据', '数据刷新中...'];
const PULL_DOWN_HEIGHT = 80;
/**
 * reset the status of pull down
 * @param {Object} pullDown the pull down
 */
let resetPullDown = pullDown => {
    pullDown.height = 0;
    pullDown.status = STATUS_START;
};

export default {
  name:'PullRefresh',
  props: {
    onRefresh: {
      type: Function
    },
    config: {
      type: Object,
      default() {
        return {};
      }
    },
    isLock: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      pullDown:{
        status: 0,
        height: 0,
        msg: ''
      },
      touchPosition:{
        start: 0,
        distance: 0
      },
      pullDownHeader: null,
      icon: null,
    }
  },
  computed: {
    label(){
      if(this.pullDown.status === STATUS_ERROR){
        return this.pullDown.msg
      }
      return this.customLabels[this.pullDown.status + 1]
    },
    customLabels(){
      let errorLabel = this.config.errorLabel || LABELS[0]
      let startLabel = this.config.startLabel || LABELS[1]
      let readyLaebl = this.config.readyLabel || LABELS[2]
      let loadingLabel = this.config.loadingLabel || LABELS[3]
      return [errorLabel, startLabel, readyLaebl, loadingLabel]
    },
    iconClass(){
      if (this.pullDown.status === STATUS_REFRESH) {
          return 'pull-down-refresh'
      } else if (this.pullDown.status === STATUS_ERROR) {
          return 'pull-down-error'
      }
      return ''
    }
  },
  mounted(){
    let el = this.$el
    this.pullDownHeader = el.querySelector('.pull-down-header')
    this.icon = el.querySelector('.pull-down-content--icon')
  },
  methods: {
    touchstart(e){
      this.touchPosition.start = e.touches[0].pageY
    },
    touchmove(e){
      if(this.isLock) return
      e.preventDefault()

      let distance = e.touches[0].pageY - this.touchPosition.start
      distance = distance > 180 ? 180 : distance

      this.touchPosition.distance = distance
      this.pullDown.height = distance

      if(distance > PULL_DOWN_HEIGHT){
        this.pullDown.status = STATUS_READY
        this.icon.style.transform = 'rotate(180deg)'
      } else {
        this.pullDown.status = STATUS_START
        this.icon.style.transform = `rotate(${ distance / PULL_DOWN_HEIGHT * 180 }deg)`
      }
    },
    touchend(e){
      this.pullDownHeader.style.transition = 'height .2 ease'
      this.icon.style.transform = ''

      if(this.touchPosition.distance > PULL_DOWN_HEIGHT){
        this.pullDown.height = PULL_DOWN_HEIGHT
        this.pullDown.status = STATUS_REFRESH

        if(this.onRefresh && typeof this.onRefresh === 'function'){
          let res = this.onRefresh()
          if(res && res.then && typeof res.then === 'function'){
            res.then(result => {
              resetPullDown(this.pullDown)
            })
            .catch(e => {
              this.pullDown.msg = e || this.customLabels[0]
              this.pullDown.status = STATUS_ERROR
              setTimeout(() => {
                resetPullDown(this.pullDown)
              }, 1000)
            })
          }
        } else {
          setTimeout(() => {
            resetPullDown(this.pullDown)
          }, 1000)
          console.warn('please use :on-refresh to pass onRefresh callback')
        }
      } else {
        resetPullDown(this.pullDown)
      }

      this.touchPosition.distance = 0
      this.touchPosition.start = 0
    },
    transitionend(e){
      e.target.style.transition = ''
    }
  }
}
</script>

<style lang="scss" scoped>
//基于750px设计
.pull-down-header {
    width: 100%;
    height: 80px;
    overflow: hidden;
    position: relative;
    background-color: #2c3133;
}
.pull-down-content {
    position: absolute;
    max-width: 90%;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    height: 40px;
    color: #d5d5d5;
    text-align: center;
    border-left: 20px solid transparent;
    font-family: "noto-thin", "Helvetica Neue", Helvetica, Arial, sans-serif;
    font-size: 26px;
    &--icon {
        float: left;
        height: 30px;
        width: 30px;
        margin-top: 5px;
        margin-left: -30px;
        background: url(./down-arrow.png) no-repeat center center;
        background-size: 30px 30px;
        &.pull-down-refresh {
            background: url(./refresh-icon.png) no-repeat center center;
            background-size: 30px 30px;
            animation: rotate 2s infinite;
            animation-timing-function: linear;
        }
        &.pull-down-error {
            background: url(./error-icon.png) no-repeat center center;
            background-size: 30px 30px;
        }
    }
    &--label {
        float: left;
        height: 20px;
        line-height: 20px;
        margin-left: 10px;
        margin-top: 10px;
    }
}
@keyframes rotate {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}
</style>
